#!/bin/sh
#
# Copyright (C) 2017 Ruilin Peng (Nick) <pymumu@gmail.com>
#

INST_DIR=$(cd $(dirname $0);pwd)

showhelp()
{
	echo "Usage: install [OPTION]"
	echo "Options:"
	echo " -i               install jail-shell."
	echo " -u               uninstall jail-shell."
	echo " --prefix [dir]   prefix directory."
	echo " -h               show this message."
}

start_service()
{
	if [ $ISSYSTEMD -ne 0 ]; then
		chkconfig jail-shell on
		service jail-shell start
		return $?
	fi

	systemctl daemon-reload
	systemctl enable jail-shell
	systemctl start jail-shell
}

stop_service()
{
	if [ $ISSYSTEMD -ne 0 ]; then
		service jail-shell stop
		chkconfig jail-shell off
		return 0
	fi

	systemctl stop jail-shell
	systemctl disable jail-shell

	return 0
}

clean_service()
{
	if [ $ISSYSTEMD -ne 0 ]; then
		return 0
	fi
	systemctl daemon-reload
}

add_system_depdence_libs()
{
	SAMPLE_FILE=$1
	LIBC_PATH="`ldd /bin/sh | grep libc.so | awk '{print $3}'`"
	LIB_PATH="`dirname $LIBC_PATH`"
	LIBNSS_COMP="`ldconfig -p | grep "libnss_compat.so\." | grep $LIB_PATH | awk -F"=>" '{print $2}'`"
	LIBNSS_FILES="`ldconfig -p | grep "libnss_files.so\." | grep $LIB_PATH | awk -F"=>" '{print $2}'`"
	LIBNSS_DNS="`ldconfig -p | grep "libnss_dns.so\." | grep $LIB_PATH | awk -F"=>" '{print $2}'`"
	LIBDIR="`dirname $LIBNSS_DNS`"

	echo "" >> $SAMPLE_FILE
	echo "# Basic library list" >> $SAMPLE_FILE
	if [ "`dirname $LIBDIR`" != "/" ]; then
		echo "dir `dirname $LIBDIR` 0755 root:root" >> $SAMPLE_FILE
	fi
	echo "dir `dirname $LIBNSS_DNS` 0755 root:root" >> $SAMPLE_FILE
	echo "clink $LIBNSS_COMP $LIBNSS_COMP" >> $SAMPLE_FILE
	echo "clink $LIBNSS_FILES $LIBNSS_FILES" >> $SAMPLE_FILE
	echo "clink $LIBNSS_DNS $LIBNSS_DNS" >> $SAMPLE_FILE
}

get_systemd_path()
{
	service="`systemctl --no-legend| grep .service | head -n 1 | awk '{print $1}'`"
	SERVICE_PATH="`systemctl show $service | grep FragmentPath | awk -F'=' '{print $2}'`"
	dirname $SERVICE_PATH
}

install_files()
{
	install -v -d $JAIL_SHELL_HOME_DIR $JAIL_SHELL_HOME_DIR/jail-cmd/ $JAIL_SHELL_CONF_DIR/jail-config \
		$JAIL_SHELL_CONF_DIR $JAIL_SHELL_HOME_DIR/misc $JAIL_SHELL_HOME_DIR/bin 
	if [ $? -ne 0 ]; then
		return 1
	fi
	
	install -v -m 0755  -t $JAIL_SHELL_HOME_DIR/jail-cmd/ jail-cmd/jail-cmd jail-cmd/jail-cmdd 
	if [ $? -ne 0 ]; then
		return 1
	fi

	ln -v -f -s /usr/local/jail-shell/jail-cmd/jail-cmdd $PREFIX/usr/sbin/jail-cmdd 
	if [ $? -ne 0 ]; then
		return 1
	fi

	install -v -m 0755 -t $JAIL_SHELL_HOME_DIR/bin bin/jail-shell bin/jail-shell-setup bin/jail-shell-post pam_jail_shell/jail-init
	if [ $? -ne 0 ]; then
		return 1
	fi

	ln -v -f -s /usr/local/jail-shell/bin/jail-shell $PREFIX/usr/sbin/jail-shell
	if [ $? -ne 0 ]; then
		return 1
	fi

	install -v -m 0755  -t  $SECURITY_DIR pam_jail_shell/pam_jail_shell.so 
	if [ $? -ne 0 ]; then
		return 1
	fi
	#for selinux, change permission to lib_t
	chcon --type lib_t $SECURITY_DIR/pam_jail_shell.so >/dev/null 2>&1

	if [ ! -f "$PREFIX$JAIL_SHELL_CONF_DIR/jail-shell.conf" ]; then
		install -v -m 0600 -t  $PREFIX$JAIL_SHELL_CONF_DIR pam_jail_shell/jail-shell.conf 
		if [ $? -ne 0 ]; then
			return 1
		fi
	fi

	ln -v -f -s  $JAIL_SHELL_CONF_DIR/jail-shell.conf /etc/security/jail-shell.conf
	if [ $? -ne 0 ]; then
		return 1
	fi
	
	install -v -m 0755 -t $JAIL_SHELL_INIT_DIR etc/init.d/jail-shell 
	if [ $? -ne 0 ]; then
		return 1
	fi

	if [ $ISSYSTEMD -eq 0 ]; then
		SYSTEM_UNIT_PATH="`get_systemd_path`"
		if [ -z "$SYSTEM_UNIT_PATH" ]; then
			return 1
		fi
		install -v -m 0644 -t $PREFIX$SYSTEM_UNIT_PATH lib/systemd/system/jail-shell.service 
		if [ $? -ne 0 ]; then
			return 1
		fi
	fi

	install -v -m 0644 -t $PREFIX/etc/default etc/default/jail-shell 
	if [ $? -ne 0 ]; then
		return 1
	fi

	install -v -t $JAIL_SHELL_CONF_DIR etc/jail-shell/cmd_config etc/jail-shell/cmdd_config -m 644
	if [ $? -ne 0 ]; then
		return 1
	fi

	install -v -t $JAIL_SHELL_CONF_DIR/jail-config etc/jail-shell/jail-config/*.sample -m 640
	if [ $? -ne 0 ]; then
		return 1
	fi

	install -v -t $JAIL_SHELL_HOME_DIR install -m 755
	if [ $? -ne 0 ]; then
		return 1
	fi

	add_system_depdence_libs $JAIL_SHELL_CONF_DIR/jail-config/jail.cfg.sample
	add_system_depdence_libs $JAIL_SHELL_CONF_DIR/jail-config/jail-bin-symbolic-link.cfg.sample

	cp misc/* $JAIL_SHELL_HOME_DIR/misc/ -avf
	if [ $? -ne 0 ]; then
		return 1
	fi

	chmod 0644 $JAIL_SHELL_HOME_DIR/misc/ -R
	if [ $? -ne 0 ]; then
		return 1
	fi

	add_pam_config
	if [ $? -ne 0 ]; then
		return 1
	fi

	return 0
}

remove_pam_config()
{
	sed -i '/pam_jail_shell.so/d' $PREFIX/etc/pam.d/common-session 2>/dev/null 
	sed -i '/pam_jail_shell.so/d' $PREFIX/etc/pam.d/login 2>/dev/null
	sed -i '/pam_jail_shell.so/d' $PREFIX/etc/pam.d/sshd 2>/dev/null
	sed -i '/pam_jail_shell.so/d' $PREFIX/etc/pam.d/su 2>/dev/null
}


add_pam_config() 
{
	remove_pam_config
	if [ -e "$PREFIX/etc/pam.d/common-session" ]; then
		echo "session required		pam_jail_shell.so" >> $PREFIX/etc/pam.d/common-session 2>/dev/null
		if [ $? -eq 0 ]; then
			return 0
		fi
		return 1
	fi

	echo "session required		pam_jail_shell.so" >> $PREFIX/etc/pam.d/login 2>/dev/null
	if [ $? -ne 0 ]; then
		return 1
	fi

	echo "session required		pam_jail_shell.so" >> $PREFIX/etc/pam.d/sshd 2>/dev/null
	if [ $? -ne 0 ]; then
		return 1
	fi

	echo "session required		pam_jail_shell.so" >> $PREFIX/etc/pam.d/su 2>/dev/null
	if [ $? -ne 0 ]; then
		return 1
	fi

	return $?
}


uninstall_jail_shell()
{
	if [ -z "$PREFIX" ]; then
		remove_pam_config
		stop_service
	fi	
	rm -fr $JAIL_SHELL_HOME_DIR
	rm -fr $JAIL_SHELL_CONF_DIR/jail-shell.conf
	rm -fr $JAIL_SHELL_CONF_DIR/cmd_config 
	rm -fr $JAIL_SHELL_CONF_DIR/cmdd_config
	rm -fr $JAIL_SHELL_CONF_DIR/jail-config/*.sample
	rmdir  $JAIL_SHELL_CONF_DIR/jail-config 2>/dev/null
	rmdir  $JAIL_SHELL_CONF_DIR 2>/dev/null
	rm -fr $JAIL_SHELL_INIT_DIR/jail-shell
	rm -fr $PREFIX/usr/sbin/jail-cmdd
	rm -fr $PREFIX/usr/sbin/jail-shell
	rm -fr $SECURITY_DIR/pam_jail_shell.so
	rm -fr $PREFIX/etc/security/jail-shell.conf
	rm -fr $PREFIX/etc/default/jail-shell

	if [ $ISSYSTEMD -eq 0 ]; then
		SYSTEM_UNIT_PATH="`get_systemd_path`"
		if [ ! -z "$SYSTEM_UNIT_PATH" ]; then
			rm -f $PREFIX/$SYSTEM_UNIT_PATH/jail-shell.service
		fi
	fi

	if [ -z "$PREFIX" ]; then
		clean_service
	fi	

	printf "\033[31mjail home /var/local/jail-shell is not deleted, please check and delete manually.\033[0m\n"
}


install_jail_shell()
{
	local ret

	install_files
	ret=$?
	if [ $ret -ne 0 ]; then
		uninstall_jail_shell
		return $ret
	fi

	if [ -z "$PREFIX" ]; then
		start_service
	fi

	return 0
}



init_dir()
{
	JAIL_SHELL_HOME_DIR=$PREFIX/usr/local/jail-shell
	JAIL_SHELL_CONF_DIR=$PREFIX/etc/jail-shell
	JAIL_SHELL_INIT_DIR=$PREFIX/etc/init.d
	LIB_DIR=$PREFIX"`ldd /bin/sh | grep libc | awk '{print $3}' | xargs dirname`"
	SECURITY_DIR=$LIB_DIR/security
	which systemctl >/dev/null 2>&1
	ISSYSTEMD="$?"

	cd $INST_DIR
}

main()
{
	ACTION=""

	OPTS=`getopt -o iuh --long help,prefix: \
		-n  "" -- "$@"`

	if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi

	# Note the quotes around `$TEMP': they are essential!
	eval set -- "$OPTS"

	while true; do
		case "$1" in
		--prefix)
			PREFIX="$2"
			shift 2;;
		-h | --help )
			showhelp
			return 0
			shift ;;
		-i )
			ACTION="INSTALL"
			shift ;;
		-u )
			ACTION="UNINSTALL"
			shift ;;
		-- ) shift; break ;;
		* ) break ;;
  		esac
	done

	init_dir

	if [ -z "$ACTION" ]; then
		showhelp
		return 0
	elif [ "$ACTION" = "INSTALL" ]; then
		install_jail_shell
		return $?
	elif [ "$ACTION" = "UNINSTALL" ]; then
		uninstall_jail_shell
		return 0
	fi	

}

main $@
exit $?


